home *** CD-ROM | disk | FTP | other *** search
- /*
- File: QuickTakePICT.c
-
- Contains: My Application Shell.
-
- Written by: John Wang
-
- Copyright: © 1994 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <1> 4/13/94 WJA First release. MakeQuickTakePicture call originally written
- by Wayman Askey as a sample to generate a Venus picture.
- <4> 09/30/94 JW Updated to follow the "QuickTake File Format
- Specifications for Venus/Nimbus" to the letter.
-
- To Do:
-
- */
-
- #include "MoreFilesExtras.h"
- #include "CmDriver.h"
-
- #include "QuickTakePICT.h"
-
- // Globals needed for QuickDraw bottleneck procs.
- ImageHeader gImageHeader;
- Ptr gImageBuffer;
-
- /* ------------------------------------------------------------------------- */
-
- /*
- Description: MakeQuickTakePicture()
-
- Format Params:
- Name Usage Description/Assumptions
- ---- ---- -----------------------
- imageHeader PI This contains the header to the compressed data.
- imageBuffer PI This contains the compressed data.
- colorMatrix PI Nil if not used.
- decompTable PI Nil if not used.
- picture PO A picture is created and returned. The handle is unlocked.
-
- Usage: P=Parameter,R=ReturnValue,E=External,G=FileGlobal,L=Local,I=Input,O=Output
-
- Error Handling: If noErr is returned, you can assume a valid pict file has been returned.
-
- Special Notes: xxx put other comments here xxx
-
- */
-
- OSErr InitializeImageData(ImageHeader *imageHeader, Ptr imageBuffer,
- CmColorMatrixPtr colorMatrix, BufferPtr decompTable, Ptr *imageData);
- OSErr InitializeImageDescription(ImageHeader *imageHeader, ImageDescriptionHandle *imageDesc, Size dataSize);
-
- OSErr InitializeImageData(ImageHeader *imageHeader, Ptr imageBuffer,
- CmColorMatrixPtr colorMatrix, BufferPtr decompTable, Ptr *imageData)
- {
- OSErr err;
- short headerSize;
- Size decompSize;
-
- // Initialize.
- err = noErr;
-
- // Check and initialize parameters.
- if ( imageData == nil ) {
- err = paramErr;
- goto bail;
- }
- *imageData = nil;
- if ( imageBuffer == nil ) {
- err = paramErr;
- goto bail;
- }
- if ( imageHeader == nil ) {
- err = paramErr;
- goto bail;
- }
-
- // Get decompTable size. This size should be for QT 100 or QT 150
- if ( decompTable != nil ) {
- decompSize = GetPtrSize((Ptr) decompTable);
- if ( decompSize != kCmDecompTableSize100 && decompSize != kCmDecompTableSize150 ) {
- err = paramErr;
- goto bail;
- }
- } else
- decompSize = 0;
-
- // Set headersize.
- if ( colorMatrix == nil ) {
- if ( decompTable == nil ) {
- headerSize = sizeof(ImageHeader);
- } else if ( decompTable != nil && decompSize == kCmDecompTableSize100 ) {
- headerSize = sizeof(ImageHeader_CT100);
- } else if ( decompTable != nil && decompSize == kCmDecompTableSize150 ) {
- headerSize = sizeof(ImageHeader_CT150);
- } else {
- err = paramErr;
- goto bail;
- }
- } else {
- if ( decompTable == nil ) {
- headerSize = sizeof(ImageHeader_CM);
- } else if ( decompTable != nil && decompSize == kCmDecompTableSize100 ) {
- headerSize = sizeof(ImageHeader_CM_CT100);
- } else if ( decompTable != nil && decompSize == kCmDecompTableSize150 ) {
- headerSize = sizeof(ImageHeader_CM_CT150);
- } else {
- err = paramErr;
- goto bail;
- }
- }
-
- // Check for valid signature and version.
- if ( ((imageHeader->signature == 'qktk') && (imageHeader->version == 1)) ||
- ((imageHeader->signature == 'qktn') && (imageHeader->version == 2)) ) {
-
- // Create new memory block depending on what's supposed to be in it.
- *imageData = NewPtr((imageHeader->dataSize + headerSize));
-
- // If we succeed...
- if (*imageData != nil) {
- // Append the QuickTake image header to the raw compressed image.
- if ( colorMatrix == nil ) {
- if ( decompTable == nil ) {
- BlockMove((Ptr) imageHeader, *imageData, headerSize);
- } else if ( decompTable != nil && decompSize == kCmDecompTableSize100 ) {
- ImageHeader_CT100 imageHeader_CT100;
- imageHeader_CT100.signature = imageHeader->signature;
- imageHeader_CT100.version = imageHeader->version;
- imageHeader_CT100.flags = imageHeader->flags | kQktkHasCompressionTable;
- imageHeader_CT100.compTableSize = kCmDecompTableSize100;
- imageHeader_CT100.dataSize = imageHeader->dataSize;
- BlockMove(decompTable, imageHeader_CT100.compTable, kCmDecompTableSize100);
- BlockMove((Ptr) &imageHeader_CT100, *imageData, headerSize);
- } else if ( decompTable != nil && decompSize == kCmDecompTableSize150 ) {
- ImageHeader_CT150 imageHeader_CT150;
- imageHeader_CT150.signature = imageHeader->signature;
- imageHeader_CT150.version = imageHeader->version;
- imageHeader_CT150.flags = imageHeader->flags | kQktkHasCompressionTable;
- imageHeader_CT150.compTableSize = kCmDecompTableSize150;
- imageHeader_CT150.dataSize = imageHeader->dataSize;
- BlockMove(decompTable, imageHeader_CT150.compTable, kCmDecompTableSize150);
- BlockMove((Ptr) &imageHeader_CT150, *imageData, headerSize);
- }
- } else {
- if ( decompTable == nil ) {
- ImageHeader_CM imageHeader_CM;
- imageHeader_CM.signature = imageHeader->signature;
- imageHeader_CM.version = imageHeader->version;
- imageHeader_CM.flags = imageHeader->flags | kQktkHasColorMatrix;
- imageHeader_CM.dataSize = imageHeader->dataSize;
- BlockMove(&(colorMatrix->colorCorrectionMatrix), imageHeader_CM.colorMatrix, sizeof(double[12]));
- BlockMove((Ptr) &imageHeader_CM, *imageData, headerSize);
- } else if ( decompTable != nil && decompSize == kCmDecompTableSize100 ) {
- ImageHeader_CM_CT100 imageHeader_CM_CT100;
- imageHeader_CM_CT100.signature = imageHeader->signature;
- imageHeader_CM_CT100.version = imageHeader->version;
- imageHeader_CM_CT100.flags = imageHeader->flags | kQktkHasColorMatrix | kQktkHasCompressionTable;
- imageHeader_CM_CT100.compTableSize = kCmDecompTableSize100;
- imageHeader_CM_CT100.dataSize = imageHeader->dataSize;
- BlockMove(&(colorMatrix->colorCorrectionMatrix), imageHeader_CM_CT100.colorMatrix, sizeof(double[12]));
- BlockMove(decompTable, imageHeader_CM_CT100.compTable, kCmDecompTableSize100);
- BlockMove((Ptr) &imageHeader_CM_CT100, *imageData, headerSize);
- } else if ( decompTable != nil && decompSize == kCmDecompTableSize150 ) {
- ImageHeader_CM_CT150 imageHeader_CM_CT150;
- imageHeader_CM_CT150.signature = imageHeader->signature;
- imageHeader_CM_CT150.version = imageHeader->version;
- imageHeader_CM_CT150.flags = imageHeader->flags | kQktkHasColorMatrix | kQktkHasCompressionTable;
- imageHeader_CM_CT150.compTableSize = kCmDecompTableSize150;
- imageHeader_CM_CT150.dataSize = imageHeader->dataSize;
- BlockMove(&(colorMatrix->colorCorrectionMatrix), imageHeader_CM_CT150.colorMatrix, sizeof(double[12]));
- BlockMove(decompTable, imageHeader_CM_CT150.compTable, kCmDecompTableSize150);
- BlockMove((Ptr) &imageHeader_CM_CT150, *imageData, headerSize);
- }
- }
- BlockMove(imageBuffer, (*imageData + headerSize), imageHeader->dataSize);
- } else {
- err = memFullErr;
- goto bail;
- }
- } else {
- err = paramErr;
- goto bail;
- }
-
- bail:
- return (err);
- }
-
- OSErr InitializeImageDescription(ImageHeader *imageHeader, ImageDescriptionHandle *imageDesc, Size dataSize)
- {
- OSErr err;
- Fixed resolution;
- short w, h;
-
- // Initialize.
- err = noErr;
-
- // Check and intialize parameters.
- if ( imageDesc == nil ) {
- err = paramErr;
- goto bail;
- }
- *imageDesc = nil;
- if ( imageHeader == nil ) {
- err = paramErr;
- goto bail;
- }
-
- // Check for valid signature and version.
- if ( (imageHeader->signature == 'qktk') && (imageHeader->version == 1) ) {
- if (imageHeader->flags & kQktkHiResImage) {
- resolution = Long2Fix(72L);
- w = 640;
- h = 480;
- } else if (imageHeader->flags & kQktkStdResImage) {
- resolution = Long2Fix(72L);
- w = 320;
- h = 240;
- } else if (imageHeader->flags & kQktkThumbnailImage) {
- resolution = Long2Fix(72L);
- w = 80;
- h = 60;
- } else {
- err = paramErr;
- goto bail;
- }
- } else if ( (imageHeader->signature == 'qktn') && (imageHeader->version == 2) ) {
- if (imageHeader->flags & kQktkHiResImage) {
- resolution = Long2Fix(72L);
- w = 640;
- h = 480;
- } else if (imageHeader->flags & kQktkStdResImage) {
- resolution = Long2Fix(72L);
- w = 640;
- h = 480;
- } else if (imageHeader->flags & kQktkThumbnailImage) {
- resolution = Long2Fix(72L);
- w = 80;
- h = 60;
- } else {
- err = paramErr;
- goto bail;
- }
- } else {
- err = paramErr;
- goto bail;
- }
-
- // Ok, now let's create the imageDesc.
- *imageDesc = (ImageDescriptionHandle) NewHandleClear(sizeof(ImageDescription));
- if ( *imageDesc == nil ) {
- err = memFullErr;
- goto bail;
- }
- MoveHHi((Handle) *imageDesc);
- HLock((Handle) *imageDesc);
-
- // Fill out the image description. Refer to the Image Compression
- // Manager chapter of "Inside Macintosh: QuickTime" for a compete
- // description of this data structure.
- (**imageDesc)->idSize = sizeof(ImageDescription);
- (**imageDesc)->cType = (CodecType) imageHeader->signature;
- (**imageDesc)->version = 0;
- (**imageDesc)->revisionLevel = 0;
- (**imageDesc)->vendor = 0;
- (**imageDesc)->temporalQuality = 0;
- (**imageDesc)->spatialQuality = codecNormalQuality;
- (**imageDesc)->hRes = (**imageDesc)->vRes = resolution;
- (**imageDesc)->dataSize = dataSize;
- BlockMove((Ptr)"\pQuickTake™", (Ptr)(**imageDesc)->name, 11);
- (**imageDesc)->depth = 24;
- (**imageDesc)->clutID = -1;
-
- // Determine whether image should be displayed as a vertical (width < height)
- // or horizontal (width > height) image.
- if (imageHeader->flags & kQktkVerticalImage) {
- (**imageDesc)->width = h;
- (**imageDesc)->height = w;
- } else {
- (**imageDesc)->width = w;
- (**imageDesc)->height = h;
- }
-
- bail:
- return (err);
- }
-
- OSErr MakeQuickTakePicture(ImageHeader *imageHeader, Ptr imageBuffer,
- CmColorMatrixPtr colorMatrix, BufferPtr decompTable, PicHandle *pict)
- {
- OSErr err;
- ImageDescriptionHandle imageDesc;
- Ptr imageData;
- Rect bounds;
- CGrafPtr saveport;
- GDHandle savegdevice;
- GWorldPtr myGWorld;
- OpenCPicParams myPicParams;
- Rect boundsRect = {0, 0, 8, 8};
-
- // Things that we must initialize first.
- GetGWorld(&saveport, &savegdevice);
- myGWorld = nil;
- imageDesc = nil;
- imageData = nil;
-
- if ( pict == nil ) {
- err = paramErr;
- goto bail;
- }
- *pict = nil;
- if ( imageBuffer == nil ) {
- err = paramErr;
- goto bail;
- }
- if ( imageHeader == nil ) {
- err = paramErr;
- goto bail;
- }
-
- // Rather than depend on a graphics port, we create an offscreen gworld to use as the current
- // port and gdevice for creating the picture.
- err = NewGWorld(&myGWorld, 32, &boundsRect, nil, nil, 0);
- if ( err != noErr ) {
- myGWorld = nil;
- goto bail;
- }
- if ( myGWorld == nil ) {
- err = memFullErr;
- myGWorld = nil;
- goto bail;
- }
- SetGWorld(myGWorld, nil);
-
- // If the gworld was created properly, then create imageData.
- err = InitializeImageData(imageHeader, imageBuffer, colorMatrix, decompTable, &imageData);
- if ( err != noErr ) {
- goto bail;
- }
-
- // If the gworld was created properly, then create imageDesc.
- err = InitializeImageDescription(imageHeader, &imageDesc, GetPtrSize(imageData));
- if ( err != noErr ) {
- goto bail;
- }
-
- // Create the picture.
- SetRect(&bounds, 0, 0, (**imageDesc).width, (**imageDesc).height);
- myPicParams.srcRect = bounds;
- myPicParams.hRes = (**imageDesc).hRes;
- myPicParams.vRes = (**imageDesc).vRes;
-
- // Special case for hi-res Venus pictures...
- if ( (imageHeader->signature == 'qktk') && (imageHeader->version == 1) ) {
- if (imageHeader->flags & kQktkHiResImage) {
- myPicParams.hRes = (**imageDesc).hRes << 1;
- myPicParams.vRes = (**imageDesc).vRes << 1;
- }
- // Special case for Nimbus pictures...
- } else if ( (imageHeader->signature == 'qktn') && (imageHeader->version == 2) ) {
- if (imageHeader->flags & kQktkHiResImage) {
- myPicParams.hRes = (**imageDesc).hRes << 1;
- myPicParams.vRes = (**imageDesc).vRes << 1;
- } else if (imageHeader->flags & kQktkStdResImage) {
- myPicParams.hRes = (**imageDesc).hRes << 1;
- myPicParams.vRes = (**imageDesc).vRes << 1;
- }
- }
-
- myPicParams.version = -2;
- myPicParams.reserved1 = 0;
- myPicParams.reserved2 = 0;
- *pict = OpenCPicture(&myPicParams);
- err = FDecompressImage(imageData, imageDesc, myGWorld->portPixMap, (Rect *)nil,
- (MatrixRecordPtr)nil, ditherCopy, (RgnHandle)nil, (PixMapHandle)nil, (Rect *)nil,
- codecHighQuality, anyCodec, 0L, nil, nil);
- ClosePicture();
-
- // Check for failure.
- if ( (err != noErr) || (GetHandleSize((Handle)*pict) == sizeof(Picture)) ) {
- err = (err == noErr) ? -1 : err;
- if ( *pict != nil )
- KillPicture(*pict);
- *pict = nil;
- goto bail;
- }
-
- // We will make sure the picture is unlocked now that we succeeded.
- HUnlock((Handle) *pict);
-
- bail:
- SetGWorld(saveport, savegdevice);
-
- if ( myGWorld != nil )
- DisposeGWorld(myGWorld);
- if ( imageDesc != nil )
- DisposeHandle((Handle) imageDesc);
- if ( imageData != nil )
- DisposePtr(imageData);
-
- return (err);
- }
-
- /* ------------------------------------------------------------------------- */
-
- /*
- Description: LoadThumbnailPict()
- Given a FSSpec, read in the file and try to get a thumbnail pict.
- If it is a QuickTake file, then the thumbnail is used. Otherwise, the
- thumbnail is created using the full pict. The size of the pict returned
- canbe any size. So, don't assume that it is thumbnail size.
-
- Format Params:
- Name Usage Description/Assumptions
- ---- ---- -----------------------
- theFSSpec PI Pass in a valid FSSpec to load the picture from.
- pict PO if pict is not nil, then valid PicHandle will be returned.
- The pict will be an unlocked handle.
-
- Usage: P=Parameter,R=ReturnValue,E=External,G=FileGlobal,L=Local,I=Input,O=Output
-
- Error Handling: If noErr is returned, you can assume a valid pict.
-
- Special Notes: Future Optional upgrade: use the pnot preview pict if available.
-
- */
-
- OSErr LoadThumbnailPict(FSSpec *theFSSpec, PicHandle *pict)
- {
- OSErr err;
- short myRefNum;
- long thumbnailOffset;
- long fileSize;
-
- // Initialize variables used in this function.
- myRefNum = -1;
- err = noErr;
-
- // Check parameters after initialization.
- if ( pict == nil ) {
- err = paramErr;
- goto bail;
- }
- *pict = nil;
- if ( theFSSpec == nil ) {
- err = paramErr;
- goto bail;
- }
-
- // Try data fork first. The data fork must be greater than 512 in size...
- err = FSpOpenDF(theFSSpec, fsRdPerm, &myRefNum);
- if ( err != noErr ) {
- myRefNum = -1;
- err = noErr; // Remove err and try resource fork.
- goto tryResourceFork;
- }
- err = GetEOF(myRefNum, &fileSize);
- if ( err != noErr ) {
- err = noErr; // Remove err and try resource fork.
- goto tryResourceFork;
- }
- if ( fileSize > 512 ) {
- long headerSize, pictSize, origPictSize;
- unsigned char header[512];
-
- // Read in fileHeader first.
- headerSize = 512;
- err = FSRead(myRefNum, &headerSize, header);
- if ( err != noErr )
- goto bail;
- if ( headerSize != 512 ) {
- err = ioErr;
- goto bail;
- }
-
- // If it is a valid Venus or Nimbus file header, then we will use thumbnailOffset from
- // header. We will also read in the CmPictureInfo in this case. Otherwise, don't since
- // we can't be sure of the file version and structure.
- // We check the version to make sure it is 0 since that is the file format version
- // as defined in the "QuickTake File Format Specification for Venus/Nimbus".
- if ( (((PictFileHeader *) header)->signature == 'qktk' &&
- ((PictFileHeader *) header)->version == 0) ||
- (((PictFileHeader *) header)->signature == 'qktn' &&
- ((PictFileHeader *) header)->version == 0) ) {
- thumbnailOffset = ((PictFileHeader *) header)->thumbnailOffset;
- } else
- thumbnailOffset = 0;
-
- // Read in pict. If the thumbnail exists, then read upto the thumbnail. Otherwise,
- // assume that the entire rest of file is part of picture.
- if ( thumbnailOffset > 0 )
- pictSize = thumbnailOffset - 512;
- else
- pictSize = fileSize - 512;
- origPictSize = pictSize;
-
- // Use pict if thumbnail doesn't exist.
- if ( thumbnailOffset == 0 ){
- *pict = (PicHandle) NewHandle(pictSize);
- if ( *pict == nil ) {
- err = memFullErr;
- goto bail;
- }
- MoveHHi((Handle) *pict);
- HLock((Handle) *pict);
- err = FSRead(myRefNum, &pictSize, **pict);
- if ( err != noErr )
- goto bail;
- if ( pictSize != origPictSize ) {
- err = ioErr;
- goto bail;
- }
- HUnlock((Handle) *pict);
- // Skip pict if thumbnail exists.
- } else {
- // Simply advance the file position otherwise.
- err = SetFPos(myRefNum, fsFromMark, pictSize);
- if ( err != noErr )
- goto bail;
- }
-
- // If there is a thumbnail, then continue.
- if ( thumbnailOffset != 0 ) {
- long readSize, origReadSize;
- ThumbnailHeader tempThumbnailHeader;
- Handle thumbnail;
-
- // Read in thumbnail header into tempThumbnailHeader.
- readSize = sizeof(ThumbnailHeader);
- origReadSize = readSize;
- err = FSRead(myRefNum, &readSize, &tempThumbnailHeader);
- if ( err != noErr )
- goto bail;
- if ( readSize != origReadSize) {
- err = ioErr;
- goto bail;
- }
-
- // Now read in thumbnail.
- readSize = tempThumbnailHeader.dataSize;
- origReadSize = readSize;
- thumbnail = NewHandle(readSize);
- if ( thumbnail == nil ) {
- err = memFullErr;
- goto bail;
- }
- MoveHHi(thumbnail);
- HLock(thumbnail);
- err = FSRead(myRefNum, &readSize, *thumbnail);
- if ( err != noErr ) {
- DisposeHandle(thumbnail);
- goto bail;
- }
- if ( readSize != origReadSize ) {
- DisposeHandle(thumbnail);
- err = ioErr;
- goto bail;
- }
-
- // Make a pict out of it.
- err = MakeQuickTakePicture((ImageHeader *) &tempThumbnailHeader, *thumbnail, nil, nil, pict);
- if ( err != noErr ) {
- DisposeHandle(thumbnail);
- goto bail;
- }
-
- HUnlock(thumbnail);
- DisposeHandle((Handle) thumbnail);
- }
- }
-
- // Try resource fork if we still haven't loaded a picture.
- tryResourceFork:
- // Close data fork first.
- if ( myRefNum != -1 ) {
- FSClose(myRefNum);
- myRefNum = -1;
- }
- if ( *pict == nil ) {
- short resFile;
- resFile = FSpOpenResFile(theFSSpec, fsRdPerm);
- if ( resFile == -1 ) {
- err = ioErr;
- goto bail;
- }
- *pict = (PicHandle) Get1IndResource('PICT', 1);
- if ( *pict != nil ) {
- DetachResource((Handle) *pict);
- HUnlock((Handle) *pict);
- }
- CloseResFile(resFile);
- }
-
- bail:
- // Close data fork if still opened.
- if ( myRefNum != -1 )
- FSClose(myRefNum);
-
- // Dispose if error occured.
- if ( err != noErr ) {
- if ( pict != nil ) {
- if ( *pict != nil ) {
- DisposeHandle((Handle) *pict);
- *pict = nil;
- }
- }
- }
- return ( noErr );
- }
-
- /* ------------------------------------------------------------------------- */
-
- /*
- Description: LoadPict()
- Given a FSSpec, read in the file and try to get a pict, thumbnail,
- thumnailHeader, and pictureInfo. If you don't want the pict, thumbnail, thumbnailHeader,
- or pictureInfo you can pass in nil. (i.e. You can request any combination of pict
- thumbnail, or thumbnailHeader. In fact, you can request the thumbnail
- without requesting the thumbnailHeader or vice-versa. If there is no thumbnail,
- a nil handle is returned and the thumbnailHeader will contain all 0s.)
-
- Format Params:
- Name Usage Description/Assumptions
- ---- ---- -----------------------
- theFSSpec PI Pass in a valid FSSpec to load the picture from.
- pict PO if pict is not nil, then valid PicHandle will be returned.
- The pict will be an unlocked handle.
- thumbnail PO If thumbnail is not nil, then a thumbnail will be returned if
- it exists. The thumbnail will be an unlocked handle.
- thumbnailHeader PO If thumbnailHeader is not nil, then a thumbnailHeader will be returned if
- it exists.
- pictureInfo PO if pictureInfo is not nil, then it will be returned. If there is no
- pictureInfo in the file, a zeroed out structure is returned.
-
- Usage: P=Parameter,R=ReturnValue,E=External,G=FileGlobal,L=Local,I=Input,O=Output
-
- Error Handling: If noErr is returned, you can assume a valid pict.
-
- Special Notes: xxx put other comments here xxx
-
- */
-
- OSErr LoadPict(FSSpec *theFSSpec, PicHandle *pict, Handle *thumbnail,
- ThumbnailHeader *thumbnailHeader, CmPictureInfo *pictureInfo)
- {
- OSErr err;
- short myRefNum;
- long thumbnailOffset;
- long fileSize;
-
- // Initialize variables used in this function.
- myRefNum = -1;
- err = noErr;
- if ( pict != nil )
- *pict = nil;
- if ( thumbnail != nil )
- *thumbnail = nil;
- if ( thumbnailHeader != nil ) {
- thumbnailHeader->signature = 0;
- thumbnailHeader->version = 0;
- thumbnailHeader->flags = 0;
- thumbnailHeader->dataSize = 0;
- }
- if ( pictureInfo != nil ) {
- pictureInfo->pictureNo = 0;
- pictureInfo->imageDataSize = 0;
- pictureInfo->width = 0;
- pictureInfo->height = 0;
- (pictureInfo->dateAndTime).month = 0;
- (pictureInfo->dateAndTime).day = 0;
- (pictureInfo->dateAndTime).year = 0;
- (pictureInfo->dateAndTime).hour = 0;
- (pictureInfo->dateAndTime).minute = 0;
- (pictureInfo->dateAndTime).second = 0;
- pictureInfo->flashMode = 0;
- pictureInfo->exposureTime = 0;
- pictureInfo->FNumber = 0;
- pictureInfo->pictureMode = 0;
- pictureInfo->dataCompressionMode = 0;
- pictureInfo->defectiveFlag = 0;
- }
-
- // Check parameters after initialization.
- if ( theFSSpec == nil ) {
- err = paramErr;
- goto bail;
- }
-
- // Try data fork first. The data fork must be greater than 512 in size...
- err = FSpOpenDF(theFSSpec, fsRdPerm, &myRefNum);
- if ( err != noErr ) {
- myRefNum = -1;
- err = noErr; // Remove err and try resource fork.
- goto tryResourceFork;
- }
- err = GetEOF(myRefNum, &fileSize);
- if ( err != noErr ) {
- err = noErr; // Remove err and try resource fork.
- goto tryResourceFork;
- }
- if ( fileSize > 512 ) {
- long headerSize, pictSize, origPictSize;
- unsigned char header[512];
-
- // Read in fileHeader first.
- headerSize = 512;
- err = FSRead(myRefNum, &headerSize, header);
- if ( err != noErr )
- goto bail;
- if ( headerSize != 512 ) {
- err = ioErr;
- goto bail;
- }
-
- // If it is a valid Venus or Nimbus file header, then we will use thumbnailOffset from
- // header. We will also read in the CmPictureInfo in this case. Otherwise, don't since
- // we can't be sure of the file version and structure.
- // We check the version to make sure it is 0 since that is the file format version
- // as defined in the "QuickTake File Format Specification for Venus/Nimbus".
- if ( (((PictFileHeader *) header)->signature == 'qktk' &&
- ((PictFileHeader *) header)->version == 0) ||
- (((PictFileHeader *) header)->signature == 'qktn' &&
- ((PictFileHeader *) header)->version == 0) ) {
- thumbnailOffset = ((PictFileHeader *) header)->thumbnailOffset;
- *pictureInfo = *((CmPictureInfoPtr) (header + sizeof(PictFileHeader)));
- } else
- thumbnailOffset = 0;
-
- // Read in pict. If the thumbnail exists, then read upto the thumbnail. Otherwise,
- // assume that the entire rest of file is part of picture.
- if ( thumbnailOffset > 0 )
- pictSize = thumbnailOffset - 512;
- else
- pictSize = fileSize - 512;
- origPictSize = pictSize;
-
- // Read in pict if requested.
- if ( pict != nil ) {
- *pict = (PicHandle) NewHandle(pictSize);
- if ( *pict == nil )
- goto bail;
- MoveHHi((Handle) *pict);
- HLock((Handle) *pict);
- err = FSRead(myRefNum, &pictSize, **pict);
- if ( err != noErr )
- goto bail;
- if ( pictSize != origPictSize) {
- err = ioErr;
- goto bail;
- }
- HUnlock((Handle) *pict);
- } else {
- // Simply advance the file position otherwise.
- err = SetFPos(myRefNum, fsFromMark, pictSize);
- if ( err != noErr )
- goto bail;
- }
-
- // If there is a thumbnail, then continue.
- if ( thumbnailOffset > 0 ) {
- long readSize, origReadSize;
- ThumbnailHeader tempThumbnailHeader;
-
- // Read in thumbnail header into tempThumbnailHeader.
- readSize = sizeof(ThumbnailHeader);
- origReadSize = readSize;
- err = FSRead(myRefNum, &readSize, &tempThumbnailHeader);
- if ( err != noErr )
- goto bail;
- if ( readSize != origReadSize ) {
- err = ioErr;
- goto bail;
- }
-
- // Copy tempThumbnailHeader into thumbnailHeader if requested.
- if ( thumbnailHeader != nil ) {
- *thumbnailHeader = tempThumbnailHeader;
- }
-
- // Now read in thumbnail if requested.
- readSize = tempThumbnailHeader.dataSize;
- origReadSize = readSize;
- if ( thumbnail != nil ) {
- *thumbnail = NewHandle(readSize);
- if ( *thumbnail == nil )
- goto bail;
- MoveHHi(*thumbnail);
- HLock(*thumbnail);
- err = FSRead(myRefNum, &readSize, **thumbnail);
- if ( err != noErr )
- goto bail;
- if ( readSize != origReadSize ) {
- err = ioErr;
- goto bail;
- }
-
- HUnlock(*thumbnail);
- }
- }
- }
-
- // Try resource fork if we still haven't loaded a picture.
- tryResourceFork:
- // Close data fork first.
- if ( myRefNum != -1 ) {
- FSClose(myRefNum);
- myRefNum = -1;
- }
- if ( *pict == nil ) {
- short resFile;
- resFile = FSpOpenResFile(theFSSpec, fsRdPerm);
- if ( resFile == -1 ) {
- err = ioErr;
- goto bail;
- }
- *pict = (PicHandle) Get1IndResource('PICT', 1);
- if ( *pict != nil ) {
- DetachResource((Handle) *pict);
- HUnlock((Handle) *pict);
- }
- CloseResFile(resFile);
- }
-
- bail:
- // Close data fork if still opened.
- if ( myRefNum != -1 )
- FSClose(myRefNum);
-
- // Dispose if error occured.
- if ( err != noErr ) {
- if ( pict != nil ) {
- if ( *pict != nil ) {
- DisposeHandle((Handle) *pict);
- *pict = nil;
- }
- }
- if ( thumbnail != nil ) {
- if ( *thumbnail != nil ) {
- DisposeHandle((Handle) *thumbnail);
- *thumbnail = nil;
- }
- }
- }
-
- return ( noErr );
- }
-
- /* ------------------------------------------------------------------------- */
-
- /*
- Description: SavePict()
- Given a FSSpec, save a QuickTake picture out! The file will contain a pict. SavePict() will try to
- create a proper fileHeader for the Pict. If the pict is not a Venus or Nimbus compressed picture,
- then the thumbnail and thumbnailHeader is ignored. A thumbnailHeader is required if thumbnail is passed in.
-
- Format Params:
- Name Usage Description/Assumptions
- ---- ---- -----------------------
- theFSSpec PI Pass in a valid FSSpec to load the picture from.
- creatorType PI Creator Type for the file.
- pict PI Pass in a pointer to a PicHandle. If pointer is nil, then
- a paramErr will be returned. A valid PicHandle will be returned if
- no error occured.
- thumbnail PI If thumbnail is not nil, then a thumbnail will be saved.
- thumbnailHeader must be valid.
- thumbnailHeader PI If thumbnailHeader is not nil then it will be used if thumbnail
- is valid.
- pictureInfo PI If the pictureInfo is not nil, then it will be used.
-
- Usage: P=Parameter,R=ReturnValue,E=External,G=FileGlobal,L=Local,I=Input,O=Output
-
- Error Handling: If noErr is returned, you can assume a valid pict file has been saved.
-
- Special Notes: xxx put other comments here xxx
-
- */
-
- OSErr SavePict(FSSpec *theFSSpec, OSType creatorType, PicHandle pict, Handle thumbnail,
- ThumbnailHeader *thumbnailHeader, CmPictureInfo *pictureInfo)
- {
- OSErr err;
- short myRefNum;
- short myResRefNum;
- PictFileHeader fileHeader;
- unsigned char header[512];
- long writeSize;
- long i;
- char state;
- char icnmask_vert[128] = {
- 15, 255, 255, 240, 15, 255, 255, 240, 15, 255, 255, 240, 15, 255, 255, 240,
- 15, 255, 255, 240, 15, 255, 255, 240, 15, 255, 255, 240, 15, 255, 255, 240,
- 15, 255, 255, 240, 15, 255, 255, 240, 15, 255, 255, 240, 15, 255, 255, 240,
- 15, 255, 255, 240, 15, 255, 255, 240, 15, 255, 255, 240, 15, 255, 255, 240,
- 15, 255, 255, 240, 15, 255, 255, 240, 15, 255, 255, 240, 15, 255, 255, 240,
- 15, 255, 255, 240, 15, 255, 255, 240, 15, 255, 255, 240, 15, 255, 255, 240,
- 15, 255, 255, 240, 15, 255, 255, 240, 15, 255, 255, 240, 15, 255, 255, 240,
- 15, 255, 255, 240, 15, 255, 255, 240, 15, 255, 255, 240, 15, 255, 255, 240};
- char icnmask_horiz[128] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
- // Initialize for getting pict.
- myRefNum = -1;
- myResRefNum = -1;
- err = noErr;
-
- // Check for parameter errors.
- if ( pict == nil || theFSSpec == nil ) {
- err = paramErr;
- goto bail;
- }
- if ( thumbnail != nil ) {
- if ( thumbnailHeader == nil ) {
- err = paramErr;
- goto bail;
- }
- }
-
- // Initialize variables used.
- for ( i=0; i<512; i++ ) {
- header[i] = 0;
- }
- err = GetFileHeaderFromPict(pict, &fileHeader);
- if ( err != noErr ) {
- fileHeader.signature = 0;
- fileHeader.version = 0;
- fileHeader.flags = 0;
- fileHeader.thumbnailOffset = 0;
- }
-
- // Create file.
- err = FSpCreate(theFSSpec, creatorType, 'PICT', smSystemScript);
- if ( err != noErr) {
- // If file already exists, then delete it and try again.
- if ( err == dupFNErr ) {
- err = FSpDelete(theFSSpec);
- if ( err != noErr )
- goto bail;
- err = FSpCreate(theFSSpec, creatorType, 'PICT', smSystemScript);
- if ( err != noErr )
- goto bail;
- } else
- goto bail;
- }
-
- // Write data fork.
- err = FSpOpenDF(theFSSpec, fsWrPerm, &myRefNum);
- if ( err != noErr ) {
- myRefNum = -1;
- goto bail;
- }
-
- // Create and write a fileheader. If we aren't writing thumbnail, then for thumbnailOffset to zero.
- writeSize = 512;
- ((PictFileHeader *) header)->signature = fileHeader.signature;
- ((PictFileHeader *) header)->version = fileHeader.version;
- ((PictFileHeader *) header)->flags = fileHeader.flags;
- if ( thumbnail != nil )
- ((PictFileHeader *) header)->thumbnailOffset = fileHeader.thumbnailOffset;
- else
- ((PictFileHeader *) header)->thumbnailOffset = 0;
- if ( pictureInfo != nil )
- *((CmPictureInfoPtr) (header + sizeof(PictFileHeader))) = *pictureInfo;
- err = FSWrite(myRefNum, &writeSize, header);
- if ( err != noErr )
- goto bail;
- if ( writeSize != 512 ) {
- err = ioErr;
- goto bail;
- }
-
- // Write the pict.
- writeSize = GetHandleSize((Handle) pict);
- state = HGetState((Handle) pict);
- HLock((Handle) pict);
- err = FSWrite(myRefNum, &writeSize, *pict);
- HSetState((Handle)pict, state);
- if ( err != noErr )
- goto bail;
- if ( writeSize != GetHandleSize((Handle) pict)) {
- err = ioErr;
- goto bail;
- }
-
- // Write the thumbnail header and thumbnail if we are writing out thumbnail.
- if ( (thumbnail != nil) && (fileHeader.thumbnailOffset > 0)) {
- // Write the thumbnail header.
- writeSize = sizeof(ImageHeader);
- err = FSWrite(myRefNum, &writeSize, thumbnailHeader);
- if ( err != noErr )
- goto bail;
- if ( writeSize != sizeof(ImageHeader)) {
- err = ioErr;
- goto bail;
- }
-
- // Write the thumbnail.
- writeSize = GetHandleSize(thumbnail);
- state = HGetState(thumbnail);
- HLock(thumbnail);
- err = FSWrite(myRefNum, &writeSize, *thumbnail);
- HSetState(thumbnail, state);
- if ( err != noErr )
- goto bail;
- if ( writeSize != GetHandleSize(thumbnail)) {
- err = ioErr;
- goto bail;
- }
- }
-
- // Close data fork.
- err = FSClose(myRefNum);
- myRefNum = -1;
- if ( err != noErr ) {
- goto bail;
- }
-
- // If we have, then also create custom icons.
- if ( (thumbnail != nil) ) {
- GWorldPtr myGWorld;
- PicHandle myPict;
- Rect iconRect, boundsRect = {0, 0, 32, 32};
- Handle icl8, icl4, icn;
-
- // Determine orientation.
- if ( thumbnailHeader->flags & kQktkVerticalImage )
- SetRect(&iconRect, 4, 0, 28, 32);
- else
- SetRect(&iconRect, 0, 4, 32, 28);
-
- // Create resource fork.
- FSpCreateResFile(theFSSpec, creatorType, 'PICT', nil);
- err = ResError();
- if ( err != noErr )
- goto bail;
-
- // Write resource fork.
- myResRefNum = FSpOpenResFile(theFSSpec, fsRdWrPerm);
- if ( myResRefNum == -1 ) {
- err = ioErr;
- goto bail;
- }
-
- // Create temporary picture.
- state = HGetState(thumbnail);
- HLock(thumbnail);
- err = MakeQuickTakePicture((ImageHeader *) thumbnailHeader, *thumbnail, nil, nil, &myPict);
- HSetState(thumbnail, state);
- if ( err != noErr )
- goto bail;
-
- // Create new handles needed.
- icl8 = NewHandle(1024);
- if ( icl8 == nil ) {
- DisposeHandle((Handle) myPict);
- goto bail;
- }
- MoveHHi(icl8);
- HLock(icl8);
- icl4 = NewHandle(512);
- if ( icl4 == nil ) {
- DisposeHandle((Handle) myPict);
- DisposeHandle(icl8);
- err = memFullErr;
- goto bail;
- }
- MoveHHi(icl4);
- HLock(icl4);
- icn = NewHandle(256);
- if ( icn == nil ) {
- DisposeHandle((Handle) myPict);
- DisposeHandle(icl8);
- DisposeHandle(icl4);
- err = memFullErr;
- goto bail;
- }
- MoveHHi(icn);
- HLock(icn);
-
- // Draw picture into temporary 8 bit gworld
- err = NewGWorld(&myGWorld, 8, &boundsRect, nil, nil, 0);
- if ( err == noErr ) {
- CGrafPtr saveport;
- GDHandle savegdevice;
- short rowBytes;
- Ptr from;
-
- GetGWorld(&saveport, &savegdevice);
- SetGWorld(myGWorld, nil);
- LockPixels(GetGWorldPixMap(myGWorld));
- EraseRect(&boundsRect);
- HLock((Handle) myPict);
- DrawPicture(myPict, &iconRect);
- HUnlock((Handle) myPict);
- rowBytes = (**(myGWorld->portPixMap)).rowBytes & 0x3FFF;
- from = (**(myGWorld->portPixMap)).baseAddr;
- for (i=0; i<32; i++ ) {
- BlockMove(from + (rowBytes * i) , (*icl8) + (32 * i), 32);
- }
- UnlockPixels(GetGWorldPixMap(myGWorld));
- // Put into file.
- AddResource(icl8, 'icl8', -16455, "\pCustom Icon");
- SetGWorld(saveport, savegdevice);
- DisposeGWorld(myGWorld);
- myGWorld = nil;
- } else {
- DisposeHandle(icl8);
- }
-
- // Draw picture into temporary 4 bit gworld
- err = NewGWorld(&myGWorld, 4, &boundsRect, nil, nil, 0);
- if ( err == noErr ) {
- CGrafPtr saveport;
- GDHandle savegdevice;
- short rowBytes;
- Ptr from;
-
- GetGWorld(&saveport, &savegdevice);
- SetGWorld(myGWorld, nil);
- LockPixels(GetGWorldPixMap(myGWorld));
- EraseRect(&boundsRect);
- HLock((Handle) myPict);
- DrawPicture(myPict, &iconRect);
- HUnlock((Handle) myPict);
- rowBytes = (**(myGWorld->portPixMap)).rowBytes & 0x3FFF;
- from = (**(myGWorld->portPixMap)).baseAddr;
- for (i=0; i<32; i++ ) {
- BlockMove(from + (rowBytes * i) , (*icl4) + (16 * i), 16);
- }
- UnlockPixels(GetGWorldPixMap(myGWorld));
- // Put into file.
- AddResource(icl4, 'icl4', -16455, "\pCustom Icon");
- SetGWorld(saveport, savegdevice);
- DisposeGWorld(myGWorld);
- myGWorld = nil;
- } else {
- DisposeHandle(icl4);
- }
-
- // Draw picture into temporary 1 bit gworld
- err = NewGWorld(&myGWorld, 1, &boundsRect, nil, nil, 0);
- if ( err == noErr ) {
- CGrafPtr saveport;
- GDHandle savegdevice;
- short rowBytes;
- Ptr from;
-
- GetGWorld(&saveport, &savegdevice);
- SetGWorld(myGWorld, nil);
- LockPixels(GetGWorldPixMap(myGWorld));
- EraseRect(&boundsRect);
- HLock((Handle) myPict);
- DrawPicture(myPict, &iconRect);
- HUnlock((Handle) myPict);
- rowBytes = (**(myGWorld->portPixMap)).rowBytes & 0x3FFF;
- from = (**(myGWorld->portPixMap)).baseAddr;
- for (i=0; i<32; i++ ) {
- BlockMove(from + (rowBytes*i) , (*icn) + (4*i), 4);
- }
- if ( thumbnailHeader->flags & kQktkVerticalImage )
- BlockMove(icnmask_vert , (*icn) + 128, 128);
- else
- BlockMove(icnmask_horiz , (*icn) + 128, 128);
- UnlockPixels(GetGWorldPixMap(myGWorld));
- // Put into file.
- AddResource(icn, 'ICN#', -16455, "\pCustom Icon");
- SetGWorld(saveport, savegdevice);
- DisposeGWorld(myGWorld);
- myGWorld = nil;
- } else {
- DisposeHandle(icn);
- }
-
- // Dispose temporary picture.
- DisposeHandle((Handle) myPict);
-
- // Close resource fork.
- CloseResFile(myResRefNum);
- myResRefNum = -1;
- err = ResError();
- if ( err != noErr ) {
- goto bail;
- }
-
- // Set custom icon info.
- err = FSpSetHasCustomIcon(theFSSpec);
- if ( err != noErr )
- goto bail;
- }
-
- // Done.
- err = noErr;
-
- bail:
- if ( myRefNum != -1 )
- FSClose(myRefNum);
- if ( myResRefNum != -1 )
- CloseResFile(myResRefNum);
-
- return ( err );
- }
-
- /* ------------------------------------------------------------------------- */
-
- /*
- Description: GetFileHeaderFromPict()
- Given a pict, return a proper pict file header if available!
-
- Format Params:
- Name Usage Description/Assumptions
- ---- ---- -----------------------
- pict PI Pass in a PicHandle.
- fileHeader PO A fileHeader will be returned that follows the "QuickTake File Format
- Specifications for Venus/Nimbus" specs. The thumbnail offset will be 0.
-
- Usage: P=Parameter,R=ReturnValue,E=External,G=FileGlobal,L=Local,I=Input,O=Output
-
- Error Handling: If noErr is returned, you can assume a valid fileHeader has been returned.
-
- Special Notes: xxx put other comments here xxx
-
- */
-
- pascal void MyStdPixForImageHeader(PixMap *src, Rect *srcRect, MatrixRecord *matrix, short mode, RgnHandle mask,
- PixMap *matte, Rect *matteRect, short flags);
- pascal void MyStdPixForImageHeader(PixMap *src, Rect *srcRect, MatrixRecord *matrix, short mode, RgnHandle mask,
- PixMap *matte, Rect *matteRect, short flags)
- {
- OSErr err;
- Ptr data;
- ImageHeader imageHeader;
-
- err = GetCompressedPixMapInfo(src, nil, &data, nil, nil, nil);
- if ( err == noErr ) {
- imageHeader = *((ImageHeader *) data);
- if ( (imageHeader.signature == 'qktk' && imageHeader.version == 1)
- || (imageHeader.signature == 'qktn' && imageHeader.version == 2) ) {
- gImageHeader = imageHeader;
- }
- }
- }
-
- OSErr GetFileHeaderFromPict(PicHandle pict, PictFileHeader *fileHeader)
- {
- OSErr err;
- CGrafPtr saveport;
- GDHandle savegdevice;
- GWorldPtr myGWorld;
- Rect boundsRect = {0, 0, 8, 8};
- CQDProcs bottlenecks;
- UniversalProcPtr myProc;
- char state;
-
- // Things that we must initialize first.
- GetGWorld(&saveport, &savegdevice);
- myGWorld = nil;
- gImageHeader.signature = 'none';
- gImageHeader.version = -1;
- gImageHeader.flags = 0;
- gImageHeader.dataSize = 0;
-
- if ( pict == nil ) {
- err = paramErr;
- goto bail;
- }
- if ( fileHeader == nil ) {
- err = paramErr;
- goto bail;
- }
-
- // Rather than depend on a graphics port, we create an offscreen gworld to use as the current
- // port and gdevice for creating the picture.
- err = NewGWorld(&myGWorld, 32, &boundsRect, nil, nil, 0);
- if ( err != noErr ) {
- myGWorld = nil;
- goto bail;
- }
- if ( myGWorld == nil ) {
- err = memFullErr;
- myGWorld = nil;
- goto bail;
- }
- SetGWorld(myGWorld, nil);
- LockPixels(GetGWorldPixMap(myGWorld));
-
- // If the gworld was created properly, then create fileHeader.
- SetStdCProcs(&bottlenecks);
- myProc = bottlenecks.newProc1 = (UniversalProcPtr) NewStdPixProc(MyStdPixForImageHeader);
- (*myGWorld).grafProcs = &bottlenecks;
- state = HGetState((Handle) pict);
- HLock((Handle) pict);
- DrawPicture(pict, &((**pict).picFrame));
- HSetState((Handle) pict, state);
- UnlockPixels(GetGWorldPixMap(myGWorld));
- DisposeRoutineDescriptor(myProc);
-
- // Copy it in from the global variable.
- if ( gImageHeader.signature == 'none' && gImageHeader.version == -1 ) {
- err = -1;
- goto bail;
- } else {
- (*fileHeader).signature = gImageHeader.signature;
- (*fileHeader).version = 0;
- (*fileHeader).flags = gImageHeader.flags & (kQktkStdResImage | kQktkHiResImage);
- (*fileHeader).thumbnailOffset = 512 + GetHandleSize((Handle) pict);
- }
-
- bail:
- SetGWorld(saveport, savegdevice);
-
- if ( myGWorld != nil )
- DisposeGWorld(myGWorld);
-
- return (err);
- }
-
- /* ------------------------------------------------------------------------- */
-
- /*
- Description: GetImageHeaderFromPict()
- Given a pict, return a proper image header if available!
-
- Format Params:
- Name Usage Description/Assumptions
- ---- ---- -----------------------
- pict PI Pass in a PicHandle.
- imageHeader PO An imageHeader will be returned that follows the "QuickTake File Format
- Specifications for Venus/Nimbus" specs.
-
- Usage: P=Parameter,R=ReturnValue,E=External,G=FileGlobal,L=Local,I=Input,O=Output
-
- Error Handling: If noErr is returned, you can assume a valid fileHeader has been returned.
-
- Special Notes: xxx put other comments here xxx
-
- */
-
- OSErr GetImageHeaderFromPict(PicHandle pict, ImageHeader *imageHeader)
- {
- OSErr err;
- CGrafPtr saveport;
- GDHandle savegdevice;
- GWorldPtr myGWorld;
- Rect boundsRect = {0, 0, 8, 8};
- CQDProcs bottlenecks;
- UniversalProcPtr myProc;
- char state;
-
- // Things that we must initialize first.
- GetGWorld(&saveport, &savegdevice);
- myGWorld = nil;
- gImageHeader.signature = 'none';
- gImageHeader.version = -1;
- gImageHeader.flags = 0;
- gImageHeader.dataSize = 0;
-
- if ( pict == nil ) {
- err = paramErr;
- goto bail;
- }
- if ( imageHeader == nil ) {
- err = paramErr;
- goto bail;
- }
-
- // Rather than depend on a graphics port, we create an offscreen gworld to use as the current
- // port and gdevice for creating the picture.
- err = NewGWorld(&myGWorld, 32, &boundsRect, nil, nil, 0);
- if ( err != noErr ) {
- myGWorld = nil;
- goto bail;
- }
- if ( myGWorld == nil ) {
- err = memFullErr;
- myGWorld = nil;
- goto bail;
- }
- SetGWorld(myGWorld, nil);
- LockPixels(GetGWorldPixMap(myGWorld));
-
- // If the gworld was created properly, then create fileHeader.
- SetStdCProcs(&bottlenecks);
- myProc = bottlenecks.newProc1 = (UniversalProcPtr) NewStdPixProc(MyStdPixForImageHeader);
- (*myGWorld).grafProcs = &bottlenecks;
- state = HGetState((Handle) pict);
- HLock((Handle) pict);
- DrawPicture(pict, &((**pict).picFrame));
- HSetState((Handle) pict, state);
- UnlockPixels(GetGWorldPixMap(myGWorld));
- DisposeRoutineDescriptor(myProc);
-
- // Copy it in from the global variable.
- if ( gImageHeader.signature == 'none' && gImageHeader.version == -1 ) {
- err = -1;
- goto bail;
- } else {
- *imageHeader = gImageHeader;
- }
-
- bail:
- SetGWorld(saveport, savegdevice);
-
- if ( myGWorld != nil )
- DisposeGWorld(myGWorld);
-
- return (err);
- }
-
- /* ------------------------------------------------------------------------- */
-
- /*
- Description: GetImageBufferFromPict()
- Given a pict, return a proper image buffer if available! The buffer returned
- is a Ptr which must be disposed of by the caller.
-
- Format Params:
- Name Usage Description/Assumptions
- ---- ---- -----------------------
- pict PI Pass in a PicHandle.
- imageBuffer PO A image bufer for a QuickTake pict will be returned.
-
- Usage: P=Parameter,R=ReturnValue,E=External,G=FileGlobal,L=Local,I=Input,O=Output
-
- Error Handling: If noErr is returned, you can assume a valid fileHeader has been returned.
-
- Special Notes: xxx put other comments here xxx
-
- */
-
- pascal void MyStdPixForImageBuffer(PixMap *src, Rect *srcRect, MatrixRecord *matrix, short mode, RgnHandle mask,
- PixMap *matte, Rect *matteRect, short flags);
- pascal void MyStdPixForImageBuffer(PixMap *src, Rect *srcRect, MatrixRecord *matrix, short mode, RgnHandle mask,
- PixMap *matte, Rect *matteRect, short flags)
- {
- OSErr err;
- Ptr data;
- ImageHeader imageHeader;
- Ptr tempImageBuffer;
-
- err = GetCompressedPixMapInfo(src, nil, &data, nil, nil, nil);
- if ( err == noErr ) {
- imageHeader = *((ImageHeader *) data);
- if ( (imageHeader.signature == 'qktk' && imageHeader.version == 1)
- || (imageHeader.signature == 'qktn' && imageHeader.version == 2) ) {
- // Do only the first compressed picture.
- if ( gImageBuffer == nil ) {
- tempImageBuffer = NewPtr(imageHeader.dataSize);
- if ( tempImageBuffer != nil ) {
- BlockMove(data + sizeof(ImageHeader), tempImageBuffer, imageHeader.dataSize);
- gImageBuffer = tempImageBuffer;
- }
- }
- }
- }
- }
-
- OSErr GetImageBufferFromPict(PicHandle pict, Ptr *imageBuffer)
- {
- OSErr err;
- CGrafPtr saveport;
- GDHandle savegdevice;
- GWorldPtr myGWorld;
- Rect boundsRect = {0, 0, 8, 8};
- CQDProcs bottlenecks;
- UniversalProcPtr myProc;
- char state;
-
- // Things that we must initialize first.
- GetGWorld(&saveport, &savegdevice);
- myGWorld = nil;
- gImageBuffer = nil;
-
- if ( pict == nil ) {
- err = paramErr;
- goto bail;
- }
- if ( imageBuffer == nil ) {
- err = paramErr;
- goto bail;
- }
-
- // Rather than depend on a graphics port, we create an offscreen gworld to use as the current
- // port and gdevice for creating the picture.
- err = NewGWorld(&myGWorld, 32, &boundsRect, nil, nil, 0);
- if ( err != noErr ) {
- myGWorld = nil;
- goto bail;
- }
- if ( myGWorld == nil ) {
- err = memFullErr;
- myGWorld = nil;
- goto bail;
- }
- SetGWorld(myGWorld, nil);
- LockPixels(GetGWorldPixMap(myGWorld));
-
- // If the gworld was created properly, then create fileHeader.
- SetStdCProcs(&bottlenecks);
- myProc = bottlenecks.newProc1 = (UniversalProcPtr) NewStdPixProc(MyStdPixForImageBuffer);
- (*myGWorld).grafProcs = &bottlenecks;
- state = HGetState((Handle) pict);
- HLock((Handle) pict);
- DrawPicture(pict, &((**pict).picFrame));
- HSetState((Handle) pict, state);
- UnlockPixels(GetGWorldPixMap(myGWorld));
- DisposeRoutineDescriptor(myProc);
-
- // Copy it in from the global variable.
- *imageBuffer = gImageBuffer;
- if ( gImageBuffer == nil )
- err = -1;
- bail:
- SetGWorld(saveport, savegdevice);
-
- if ( myGWorld != nil )
- DisposeGWorld(myGWorld);
-
- return (err);
- }
-
- /* ------------------------------------------------------------------------- */
-
- /*
- Description: DrawPictureWIthProgress()
- Given a pict, draw it with a progress proc!
-
- Format Params:
- Name Usage Description/Assumptions
- ---- ---- -----------------------
- pict PI Pass in a PicHandle.
- pictRect PI A fileHeader will be returned that follows the "QuickTake File Format
- Specifications for Venus/Nimbus" specs. The thumbnail offset will be 0.
-
- Usage: P=Parameter,R=ReturnValue,E=External,G=FileGlobal,L=Local,I=Input,O=Output
-
- Error Handling: none.
-
- Special Notes: xxx put other comments here xxx
-
- */
-
- pascal void MyStdPixWithProgress(PixMap *src, Rect *srcRect, MatrixRecord *matrix, short mode, RgnHandle mask,
- PixMap *matte, Rect *matteRect, short flags);
- pascal void MyStdPixWithProgress(PixMap *src, Rect *srcRect, MatrixRecord *matrix, short mode, RgnHandle mask,
- PixMap *matte, Rect *matteRect, short flags)
- {
- OSErr err;
- ImageDescriptionHandle desc;
- Ptr data;
- long bufferSize;
- ICMDataProcRecord dataProc;
- ICMProgressProcRecord progressProc;
- CGrafPtr curPort;
- PixMapHandle dst;
-
- err = GetCompressedPixMapInfo(src, &desc, &data, &bufferSize, &dataProc, &progressProc);
- GetPort((GrafPtr *) &curPort);
- dst = (*curPort).portPixMap;
- FDecompressImage(data, desc, dst, srcRect, matrix, mode, mask, &matte, matteRect, codecHighQuality,
- anyCodec, bufferSize, nil, (ICMProgressProcRecordPtr) -1);
- }
-
- void DrawPictureWithProgress(PicHandle pict, Rect *pictRect)
- {
- CQDProcs bottlenecks, *oldbottlenecks;
- CGrafPtr curPort;
- UniversalProcPtr myProc;
- char state;
-
- if ( pict == nil ) {
- return;
- }
-
- SetStdCProcs(&bottlenecks);
- myProc = bottlenecks.newProc1 = (UniversalProcPtr) NewStdPixProc(MyStdPixWithProgress);
- GetPort((GrafPtr *) &curPort);
- oldbottlenecks = (*curPort).grafProcs;
- (*curPort).grafProcs = &bottlenecks;
- state = HGetState((Handle) pict);
- HLock((Handle) pict);
- DrawPicture(pict, pictRect);
- HSetState((Handle) pict, state);
- (*curPort).grafProcs = oldbottlenecks;
- DisposeRoutineDescriptor(myProc);
-
- }
-